# -*- coding: utf-8 -*-
from typing import Tuple
import mediapipe as mp
import numpy as np

mp_pose = mp.solutions.pose
LMS = mp_pose.PoseLandmark

NAME_TO_IDX = {
    "NOSE": 0, "LEFT_EYE_INNER": 1, "LEFT_EYE": 2, "LEFT_EYE_OUTER": 3, "RIGHT_EYE_INNER": 4, "RIGHT_EYE": 5, "RIGHT_EYE_OUTER": 6,
    "LEFT_EAR": 7, "RIGHT_EAR": 8, "MOUTH_LEFT": 9, "MOUTH_RIGHT": 10,
    "LEFT_SHOULDER": 11, "RIGHT_SHOULDER": 12, "LEFT_ELBOW": 13, "RIGHT_ELBOW": 14,
    "LEFT_WRIST": 15, "RIGHT_WRIST": 16,
    "LEFT_PINKY": 17, "RIGHT_PINKY": 18, "LEFT_INDEX": 19, "RIGHT_INDEX": 20, "LEFT_THUMB": 21, "RIGHT_THUMB": 22,
    "LEFT_HIP": 23, "RIGHT_HIP": 24, "LEFT_KNEE": 25, "RIGHT_KNEE": 26,
    "LEFT_ANKLE": 27, "RIGHT_ANKLE": 28, "LEFT_HEEL": 29, "RIGHT_HEEL": 30,
    "LEFT_FOOT_INDEX": 31, "RIGHT_FOOT_INDEX": 32
}

def ema(prev, cur, alpha):
    if prev is None:
        return cur
    return prev * (1 - alpha) + cur * alpha

def compute_keypoints_xy(landmarks, w, h):
    pts = [(l.x * w, l.y * h) for l in landmarks]
    return np.array(pts, dtype=np.float32)

def shoulder_center_and_width(pts):
    l_sh = pts[LMS.LEFT_SHOULDER]
    r_sh = pts[LMS.RIGHT_SHOULDER]
    center = 0.5 * (l_sh + r_sh)
    width = float(np.linalg.norm(l_sh - r_sh) + 1e-6)
    return center, width

def angle_deg(a, b, c):
    v1 = a - b
    v2 = c - b
    n1 = np.linalg.norm(v1) + 1e-6
    n2 = np.linalg.norm(v2) + 1e-6
    cosv = np.clip(np.dot(v1, v2) / (n1 * n2), -1.0, 1.0)
    return float(np.degrees(np.arccos(cosv)))

def landmark_to_array(lm) -> Tuple[float, float, float, float]:
    return (lm.x, lm.y, lm.z, getattr(lm, "visibility", 1.0))
